package com.cinsea.project.ext;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.cinsea.common.Env;
import com.cinsea.common.ExtAction;
import com.cinsea.common.JdbcDao;
import com.cinsea.ext.project.service.ProjectService;
import com.cinsea.file.model.Filestore;
import com.cinsea.file.service.FileUpload;
import com.cinsea.file.service.FilestoreService;
import com.cinsea.hrm.service.HumanService;
import com.cinsea.htmlselect.model.Option;
import com.cinsea.htmlselect.service.OptionService;
import com.cinsea.interfaces.form.Formdata;
import com.cinsea.interfaces.form.FormdataServiceImpl;
import com.cinsea.interfaces.model.Cell;
import com.cinsea.interfaces.model.Dataset;
import com.cinsea.util.SqlUtil;
import com.cinsea.util.StringUtil;
import com.cinsea.workflow.designer.MxCellType;
import com.cinsea.workflow.designer.MxGeometryType;
import com.cinsea.workflow.designer.MxGraphModelType;
import com.cinsea.workflow.designer.RootType;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class ProjectAction extends ExtAction {
    public void execute(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        String action = StringUtil.null2String(request.getParameter("action"));
        JdbcDao jdbcDao = Env.getBean("jdbcDao");
        if (action.equals("gettasklist")) {
            String prjid = StringUtil.null2String(request.getParameter("prjid"));
            String sql = "select processid,taskname,master,planstartdate,planenddate,sjstartdate,sjenddate,wcjd,xuhao,uptask,enterdocs from ut_prjtask where deleted=0 and prjname=? order by rowindex,xuhao ";
            List tasks = jdbcDao.queryForList(sql, new Object[]{prjid});
            Map root = new HashMap();
            root.put("processid", "");
            root.put("taskname", "任务分解");
            buildTaskTree(root, tasks);
            Map result = new HashMap();
            List rows = new ArrayList();
            rows.add(root);
            result.put("Rows", rows);
            response.getWriter().println(JSON.toJSONString(result, SerializerFeature.SortField));
            return;
        }
        if (action.equals("savetasks")) {
            String prjid = StringUtil.null2String(request.getParameter("prjid"));
            String tasks = StringUtil.null2String(request.getParameter("tasks"));
            List tasklist = (List) JSON.parse(tasks);
            Map root = (Map) tasklist.get(0);
            saveTaskTree(root);
            return;
        }
        if (action.equals("delete")) {
            //先保存后删除
            String prjid = StringUtil.null2String(request.getParameter("prjid"));
            String tasks = StringUtil.null2String(request.getParameter("tasks"));
            List tasklist = (List) JSON.parse(tasks);
            Map root = (Map) tasklist.get(0);
            saveTaskTree(root);
            //delete
            String taskid = StringUtil.null2String(request.getParameter("taskid"));
            deleteTaskTree(taskid);
            return;
        }
        if (action.equals("gettrackgraph")) {
            response.setHeader("cache-control", "no-cache");
            response.setHeader("pragma", "no-cache");
            response.setHeader("expires", "Mon 1 Jan 1990 00:00:00 GMT");
            OptionService optionService = Env.getBean("optionService");
            String id = StringUtil.null2String(request.getParameter("id"));
            List process = jdbcDao.queryForList("select prjstatus from ut_prjinfomation where id=?", new Object[]{id});
            String status = "";
            if (process.size() > 0) {
                status = StringUtil.null2String(((Map) process.get(0)).get("prjstatus"));
            }
            List<Option> options = optionService.getOptionList2("40895a003652f4f90136533d8ca10004", null);
            MxGraphModelType gm = new MxGraphModelType();
            RootType rt = new RootType();
            List<MxCellType> cells = rt.getMxCell();
            MxCellType c0 = new MxCellType();
            c0.setId("0");
            cells.add(c0);
            MxCellType c1 = new MxCellType();
            c1.setId("1");
            c1.setParent("0");
            cells.add(c1);
            int initX = 10;
            int initY = 10;
            int arraySizeX = 30;
            int arraySizeY = 20;
            int i = 0;
            int x = 0;
            int y = 0;

            for (int n = 0; n < options.size(); n++) {
                Option o = options.get(n);
                MxCellType cell = new MxCellType();
                cell.setId(o.getId());
                cell.setParent("1");
                cell.setValue(o.getObjname());
                if (status.equals(o.getId()))
                    cell.setStyle("ellipse;whiteSpace=wrap;gradientColor=#66FF66");
                else
                    cell.setStyle("ellipse;whiteSpace=wrap;fillColor=white");
                cell.setVertex("1");
                List geos = cell.getContent();
                MxGeometryType geo = new MxGeometryType();
                geo.setAs("geometry");
                geo.setHeight("60");
                geo.setWidth("60");
                geo.setX("" + (initX + n * 150));
                geo.setY("" + initY);
                geos.add(geo);
                cells.add(cell);
            }


            for (int n = 0; n < options.size() - 1; n++) {
                Option o = options.get(n);
                MxCellType cell = new MxCellType();
                cell.setId("arrow" + o.getId());
                cell.setParent("1");
                cell.setValue("");
                cell.setEdge("1");
                cell.setSource(o.getId());
                cell.setTarget(options.get(n + 1).getId());
                List geos = cell.getContent();
                MxGeometryType geo = new MxGeometryType();
                geo.setAs("geometry");
                geo.setRelative("1");
                geos.add(geo);
                cells.add(cell);
            }
            gm.setRoot(rt);
            try {
                JAXBContext jaxbContext = JAXBContext.newInstance("com.cinsea.workflow.designer");
                Marshaller marshaller = jaxbContext.createMarshaller();
                marshaller.marshal(gm, response.getWriter());
            } catch (Exception e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
        if (action.equals("upload_mpp")) {
            String prjid = StringUtil.null2String(request.getParameter("prjid"));
            //获取上传文件的保存的路径path
            FilestoreService filestoreService = Env.getBean("filestoreService");
            FileUpload fileUpload = new FileUpload();
            request = fileUpload.resolveMultipart(request, Env.getRootPath() + "temp", false);
            ArrayList fileinputs = fileUpload.getFileInputnameList();
            ArrayList attachids = fileUpload.getFilestoreList();
            String pName = (String) fileinputs.get(0);
            Filestore attach = new Filestore();
            if (!StringUtil.isEmpty(pName)) {
                attach = (Filestore) attachids.get(0);
                filestoreService.createAttach(attach);
            }
            String path = attach.getObjpath();
            FormdataServiceImpl si = new FormdataServiceImpl();
            Formdata formdata = new Formdata();
            Dataset ds = new Dataset();
            //创建上传的文件对应的File对象
            File mppFile = new File(path);
            //解析上传的文件，并将获得的信息保存入库
            List<Cell> taskList = new ArrayList<Cell>();
            ProjectService parseProjectMpp = Env.getBean("projectService");
            List<Map> tasks = parseProjectMpp.parseProjectFile(mppFile);
            for (int i = 0; i < tasks.size(); i++) {

                Map map = tasks.get(i);

                if (map != null) {
                    Cell c1 = new Cell();
                    c1.setId("ut_prjtask_mpprowindex");                                        //行号
                    c1.setValue(map.get("id").toString());
                    Cell c2 = new Cell();
                    c2.setId("ut_prjtask_taskname");
                    c2.setValue(map.get("taskName").toString());
                    Cell c3 = new Cell();
                    c3.setId("ut_prjtask_sjstartdate");
                    c3.setValue(map.get("startDate").toString());
                    Cell c4 = new Cell();
                    c4.setId("ut_prjtask_sjenddate");
                    c4.setValue(map.get("endDate").toString());
                    Cell c5 = new Cell();                           //前置任务，添加的新字段
                    c5.setId("ut_prjtask_mpppretask");
                    c5.setValue(map.get("beforeTask").toString());
                    String resource = map.get("resource").toString();
                    //                    StringUtil.string2Array(str,",")
                    Cell c6 = new Cell();                           //资源，添加的新字段
                    c6.setId("ut_prjtask_master");
                    c6.setValue(resource);
                    Cell c7 = new Cell();
                    c7.setId("ut_prjtask_prjname");
                    c7.setValue(prjid);
                    Cell c8 = new Cell();
                    c8.setId("ut_prjtask_mppuptask");
                    c8.setValue(map.get("uptaskrowId").toString());
                    taskList.add(c1);
                    taskList.add(c2);
                    taskList.add(c3);
                    taskList.add(c4);
                    taskList.add(c5);
                    taskList.add(c6);
                    taskList.add(c7);
                    taskList.add(c8);
                    formdata.setOperator(Env.getRemoteUser().getId());
                    formdata.setTypeid("40895a003652f4f9013653964e6c010c");//设置挂在哪个目录下
                    ds.setMaintable(taskList);
                    formdata.setData(ds);
                    String processid = si.createFormdata(formdata);
                }
            }

            //更新数据库表中mppuptask、mpppretask、mpprowindex对应的uptask、pretask、rowindex、三个字段

            updateTaskInfo(prjid);
            response.getWriter().print("<script type='text/javascript'>parent.getFilepath('success')</script>");
            return;
        }
        if (action.equals("selectTask")) {
            String projectId = StringUtil.null2String(request.getParameter("prjid"));//项目id
            String sql = "select prjno,prjname,startdate,enddate,planstartdate,planenddate from ut_prjinfomation where processid=?";
            List list = jdbcDao.queryForList(sql, new Object[]{projectId});
            Document doc = null;
            String projectName = "";
            if (list.size() > 0) {
                Map map = (Map) list.get(0);
                projectName = StringUtil.null2String(map.get("prjname"));
                doc = createXMLDocument(map, projectId);
            }

            response.setContentType("text/xml; charset=utf-8");
            PrintWriter stream = response.getWriter();
            String xml = doc.asXML();
            stream.print(xml);
            return;
        }
    }

    private void buildTaskTree(Map currenttask, List<Map> tasklist) {
        String tid = (String) currenttask.get("processid");
        HumanService humanService = Env.getBean("humanService");
        FilestoreService filestoreService = Env.getBean("filestoreService");
        //get children
        List childlist = new ArrayList();
        for (Map row : tasklist) {
            String uptask = StringUtil.null2String(row.get("uptask"));
            if (uptask.equals(tid)) {
                Map task = new HashMap();
                task.put("processid", row.get("processid"));
                task.put("id", row.get("xuhao"));
                task.put("uptask", row.get("uptask"));
                String link = "<a href=\"javascript:open('" + row.get("processid") + "')\">" + row.get("taskname") + "</a>";
                String enterdocs = (String) row.get("enterdocs");
                String docs = "";
                if (!StringUtil.isEmpty(enterdocs)) {
                    String[] attachids = StringUtil.string2Array(enterdocs, ",");
                    for (String attachid : attachids) {
                        Filestore fs = filestoreService.get(attachid);
                        if (fs != null && fs.getObjname() != null) {
                            docs += "<a href='/filedownload.do?download=1&attachid=" + fs.getId() + "'>" + fs.getObjname() + "</a>&nbsp;";
                        }
                    }
                }
                task.put("taskname", link);
                String master = (String) row.get("master");
                master = humanService.get(master).getObjname();
                task.put("master", master);
                task.put("planstartdate", row.get("planstartdate"));
                task.put("planenddate", row.get("planenddate"));
                task.put("sjstartdate", row.get("sjstartdate"));
                task.put("sjenddate", row.get("sjenddate"));
                String wcjd = StringUtil.null2String(row.get("wcjd"), "0");
                String chartstr = wcjd;
                if (!StringUtil.isEmpty(wcjd)) {
                    chartstr = "<div>\n" +
                            " <div style=\"width: auto; height: 15px;\"  class=\"x-progress-wrap left-align\">\n" +
                            "          <div class=\"x-progress-inner\">\n" +
                            "              <div style=\"width: " + wcjd + "%; height: 15px;\" id=\"ext-gen9\" class=\"x-progress-bar\">\n" +
                            "              <div style=\"z-index: 99; width: 100px;\"  class=\"x-progress-text x-progress-text-back\">" +
                            "           <div style=\"width: 100px; height: 15px;\" >" + wcjd + "%" + "</div>" +
                            "             </div>\n" +
                            "           </div>\n" +
                            "          </div>\n" +
                            "      </div>\n" +
                            "  </div>";
                }

                task.put("wcjd", chartstr);
                task.put("enterdocs", docs);
                childlist.add(task);
                buildTaskTree(task, tasklist);
            }
        }
        currenttask.put("children", childlist);
    }

    private void saveTaskTree(Map currenttask) {
        String tid = (String) currenttask.get("processid");
        JdbcDao jdbcDao = Env.getBean("jdbcDao");
        String sql = "update ut_prjtask set xuhao=?,rowindex=? where processid=?";
        String id = (String) currenttask.get("id");
        String index = String.valueOf(currenttask.get("__index"));
        if (!StringUtil.isEmpty(tid)) {
            jdbcDao.update(sql, new Object[]{id, index, tid});
        }
        //get children
        List<Map> childlist = (List) currenttask.get("children");
        for (Map row : childlist) {
            tid = (String) row.get("processid");
            id = (String) row.get("id");
            index = String.valueOf(row.get("__index"));
            jdbcDao.update(sql, new Object[]{id, index, tid});
            saveTaskTree(row);

        }
    }

    private void deleteTaskTree(String taskid) {
        JdbcDao jdbcDao = Env.getBean("jdbcDao");
        String sql = "update ut_prjtask set deleted=1 where processid=?";
        if (!StringUtil.isEmpty(taskid)) {
            jdbcDao.update(sql, new Object[]{taskid});
        }
        //delete children
        sql = "select processid from ut_prjtask  where uptask=?";
        List<Map> childlist = jdbcDao.queryForList(sql, new Object[]{taskid});
        for (Map row : childlist) {
            String tid = (String) row.get("processid");
            deleteTaskTree(tid);

        }
    }

    /**
     * 更新数据库表中mppuptask、mpppretask、mpprowindex对应的uptask、pretask、rowindex、三个字段
     *
     * @param prjid
     */
    private void updateTaskInfo(String prjid) {
        JdbcDao jdbcDao = Env.getBean("jdbcDao");
        Map mpprowindexMap = new HashMap();//以mpprowindex为键，processid为值
        List list = new ArrayList();
        String sql = "select processid,mpprowindex from ut_prjtask where prjname=?";
        list = jdbcDao.queryForList(sql, new Object[]{prjid});
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Map map = (Map) list.get(i);
                String processid = StringUtil.null2String(map.get("processid"));
                String mpprowindex = StringUtil.null2String(map.get("mpprowindex"));
                mpprowindexMap.put(mpprowindex, processid);//以mpprowindex为键，processid为值
            }
        }
        sql = "select * from ut_prjtask where prjname=?";
        list = jdbcDao.queryForList(sql, new Object[]{prjid});
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Map taskMap = (Map) list.get(i);
                String currentProcessid = StringUtil.null2String(taskMap.get("processid"));
                String mppuptask = StringUtil.null2String(taskMap.get("mppuptask"));
                String mpppretask = StringUtil.null2String(taskMap.get("mpppretask"));
                String uptaskProcessid = null;
                if (!mppuptask.equals("")) {
                    uptaskProcessid = StringUtil.null2String(mpprowindexMap.get(mppuptask));
                }
                String pretaskProcessid = null;
                if (!mpppretask.equals("")) {
                    pretaskProcessid = StringUtil.null2String(mpprowindexMap.get(mpppretask));
                }
                String updateSQL = "update ut_prjtask set uptask=?,pretask=? where prjname=? and processid=?";
                jdbcDao.update(updateSQL, new Object[]{uptaskProcessid, pretaskProcessid, prjid, currentProcessid});
            }
        }
    }

    /**
     * 递归查询任务信息，并根据task构建成一个树形结构的XML
     *
     * @param project
     * @param uptask
     */
    private void addTaskElement(Element project, String uptask, String prjName) {
        JdbcDao jdbcDao = Env.getBean("jdbcDao");
        List tasks;
        if (StringUtil.isEmpty(uptask)) {
            String sql = "select id,xuhao,pretask,taskname,uptask,planstartdate,planenddate,sjstartdate,sjenddate,wcjd from ut_prjtask where deleted=0 and " + SqlUtil.isNull("uptask") + " and prjname=?";
            tasks = jdbcDao.queryForList(sql, new Object[]{prjName});
        } else {
            String sql = "select id,xuhao,pretask,taskname,uptask,planstartdate,planenddate,sjstartdate,sjenddate,wcjd from ut_prjtask where deleted=0 and uptask=? and prjname=?";
            tasks = jdbcDao.queryForList(sql, new Object[]{uptask, prjName});
        }

        if (tasks.size() > 0) {
            for (Object obj : tasks) {
                Map map = (Map) obj;
                Element task = project.addElement("task");
                task.addAttribute("id", map.get("id").toString());
                Element name = task.addElement("name");
                String nameVal = StringUtil.null2String(map.get("taskname"));
                name.setText(nameVal);
                Element est = task.addElement("est");
                String sjstartdate = StringUtil.null2String(map.get("sjstartdate"));
                String sjenddate = StringUtil.null2String(map.get("sjenddate"));
                String estVal = "";
                String estend = "";
                String durationVal = "";
                if (!StringUtil.isEmpty(sjstartdate)) {
                    estVal = sjstartdate;
                } else {
                    String planstartdate = StringUtil.null2String(map.get("planstartdate"));
                    estVal = planstartdate;
                }
                if (!StringUtil.isEmpty(sjenddate)) {
                    durationVal = getDuration(estVal, sjenddate);
                } else {
                    String planenddate = StringUtil.null2String(map.get("planenddate"));
                    durationVal = getDuration(estVal, planenddate);
                }

                est.setText(estVal.replaceAll("-", ","));
                Element duration = task.addElement("duration");
                duration.setText(durationVal);
                Element percentcompleted = task.addElement("percentcompleted");
                String percentcompletedVal = StringUtil.null2String(map.get("wcjd"), "0");
                percentcompleted.setText(percentcompletedVal);
                Element predecessortasks = task.addElement("predecessortasks");
                predecessortasks.setText(StringUtil.null2String(map.get("pretask")));
                Element cildtasks = task.addElement("childtasks");
                addTaskElement(cildtasks, map.get("id").toString(), prjName);//递归
            }
        }
    }

    /**
     * 创建gantt需要的xml文档
     *
     * @param map
     * @return
     */
    private Document createXMLDocument(Map map, String prjName) {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("projects");
        Element project = root.addElement("project");
        String idVal = StringUtil.null2String(map.get("prjno"));
        project.addAttribute("id", idVal);
        String sjstartdate = StringUtil.null2String(map.get("startdate"));
        String planstartdate = StringUtil.null2String(map.get("planstartdate"));
        String startdateVal = sjstartdate;
        if (StringUtil.isEmpty(startdateVal)) startdateVal = planstartdate;
        project.addAttribute("startdate", startdateVal.replaceAll("-", ","));
        String nameVal = StringUtil.null2String(map.get("prjname"));
        project.addAttribute("name", nameVal);
        addTaskElement(project, "", prjName);//查询某个项目下的第一级任务，所以其uptask字段为空字符串
        return document;
    }

    /**
     * 计算两个日期之间相差的天数，从而获得duration（小时）=天数*8
     *
     * @param startDate
     * @param endDate
     * @return
     */
    private String getDuration(String startDate, String endDate) {
        String duration = "";
        try {
            if (startDate.trim().length() > 0 && endDate.trim().length() > 0) {

                DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                Date sDate = df.parse(startDate);
                Date eDate = df.parse(endDate);
                long date = eDate.getTime() - sDate.getTime();
                date = date / (24 * 60 * 60 * 1000);//计算天数
                long hour = date * 8;
                hour = hour + 8;
                duration = StringUtil.null2String(hour);//肯定是不会超过2的31次方
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return duration;
    }


}
